//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//


/*============================================================
**
** Header: COMThreadPool.h
**
** Purpose: Native methods on System.ThreadPool
**          and its inner classes
**
**
===========================================================*/

#ifndef _COMTHREADPOOL_H
#define _COMTHREADPOOL_H

#include "delegateinfo.h"
#include "nativeoverlapped.h"

class ThreadPoolNative
{

public:

    static void Init();

    static FCDECL2(FC_BOOL_RET, CorSetMaxThreads, DWORD workerThreads, DWORD completionPortThreads);
    static FCDECL2(VOID, CorGetMaxThreads, DWORD* workerThreads, DWORD* completionPortThreads);
    static FCDECL2(FC_BOOL_RET, CorSetMinThreads, DWORD workerThreads, DWORD completionPortThreads);
    static FCDECL2(VOID, CorGetMinThreads, DWORD* workerThreads, DWORD* completionPortThreads);
    static FCDECL2(VOID, CorGetAvailableThreads, DWORD* workerThreads, DWORD* completionPortThreads);

    static FCDECL0(VOID, NotifyRequestProgress);
    static FCDECL0(FC_BOOL_RET, NotifyRequestComplete);

    static void QCALLTYPE InitializeVMTp(CLR_BOOL* pEnableWorkerTracking);

    static FCDECL1(void, ReportThreadStatus, CLR_BOOL isWorking);

    static FCDECL0(FC_BOOL_RET, IsThreadPoolHosted);


    static FCDECL7(LPVOID, CorRegisterWaitForSingleObject,
                                Object* waitObjectUNSAFE,
                                Object* stateUNSAFE,
                                UINT32 timeout,
                                CLR_BOOL executeOnlyOnce,
                                Object* registeredWaitObjectUNSAFE,
                                StackCrawlMark* stackMark,
                                CLR_BOOL compressStack);

    static BOOL QCALLTYPE RequestWorkerThread();

    static FCDECL1(FC_BOOL_RET, CorPostQueuedCompletionStatus, LPOVERLAPPED lpOverlapped);    
    static FCDECL2(FC_BOOL_RET, CorUnregisterWait, LPVOID WaitHandle, Object * objectToNotify);
    static FCDECL1(void, CorWaitHandleCleanupNative, LPVOID WaitHandle);
    static FCDECL1(FC_BOOL_RET, CorBindIoCompletionCallback, HANDLE fileHandle);
};

class AppDomainTimerNative
{
public:
    static HANDLE QCALLTYPE CreateAppDomainTimer(INT32 dueTime);
    static BOOL QCALLTYPE ChangeAppDomainTimer(HANDLE hTimer, INT32 dueTime);
    static BOOL QCALLTYPE DeleteAppDomainTimer(HANDLE hTimer);
};

void ResetThreadSecurityState(Thread* pThread);
VOID QueueUserWorkItemManagedCallback(PVOID pArg);
void WINAPI BindIoCompletionCallbackStub(DWORD ErrorCode,
                                         DWORD numBytesTransferred,
                                         LPOVERLAPPED lpOverlapped);
void SetAsyncResultProperties(
    OVERLAPPEDDATAREF overlapped,
    DWORD dwErrorCode, 
    DWORD dwNumBytes);

// this holder resets our thread's security state
typedef Holder<Thread*, DoNothing<Thread*>, ResetThreadSecurityState> ThreadSecurityStateHolder;

#endif
